import cache from './cache.js';
import ajax from './axios-core.js';
// import { Modal } from 'ant-design-vue';
import html2pdf from './html2pdf.js'
import mediaParse from './mediaParse/index.js'
import schemeCheck from './schemeCheck/index.js'
import Toast from '@/components/modal/toast'
// import conf from './config.js'
import conf from "@/config/index"
import { useBroadcastChannel } from '@vueuse/core'
import { watch } from 'vue'
/**
 * 公共数据
 * @type {Object}
 */
const myData={
	conf
};
/**
 * 公共处理方法
 * @Author Mumu 175588516@qq.com
 * @type {Object}
 */
const myfun={
	/**
	 * 格式化一个时间戳
	 * @param  {[type]} fmt 格式化方式   说明：
						Y   4位数字年，y为2位数字，如99即1999年
						m   数字月份，有前导0 M无前导0
						d   月份中的第几天，有前导0 D无前导0
						h   24小时格式，有前导0，H无前导0
						g   12小时格式，有前导0，G无前导0
						i   分钟格式，有前导0  I无前导0
						s   秒格式，有前导0  S无前导0
	 * @param  {[type]} s   需要 返回的时间参数  默认fmt
	 * @param  {[type]} tm   使用时间 默认当前时间
	 * @return {[type]}     [description]
	 */
	timef(tm,fmt,allobj){
		if(tm==='now'){ tm=new Date() }
		if(!tm){return ''}
		if (!fmt) { fmt='Y-m-d H:i:s' }
		var t = {       fmt       :        fmt        ||       'Y-m-d H:i:s'       };
		tm    = (isNaN(tm)||tm.constructor==Date)?tm:(parseInt(tm)*1000||new Date());
		tm	  = typeof tm == 'string'?tm.replace(/-/g, '/'):tm;//兼容苹果系统处理
		var today=new Date(tm);
		t.time=	today.getTime();
		t.Y   =  today.getFullYear();
		t.y   =  (t.Y+'').slice(-2);
		t.M   =  today.getMonth()+1;
		t.m   =  t.M<10?"0"+t.M:t.M;
		t.D   =  today   .getDate();
		t.d   =  t.D<10?"0"+t.D:t.D;
		t.H   =  today  .getHours();
		t.h   =  t.H<10?"0"+t.H:t.H;
		t.G   =  t.H>12? t.H-12:t.H;
		t.g   =  t.G<10?"0"+t.G:t.G;
		t.I   =  today.getMinutes();
		t.i   =  t.I<10?"0"+t.I:t.I;
		t.S   =  today.getSeconds();
		t.s   =  t.S<10?"0"+t.S:t.S;
		t.K   =  today.getDay();
		t.fmt = t.fmt.replace(/Y/g,t.Y)
					 .replace(/y/g,t.y)
					 .replace(/M/g,t.M)
					 .replace(/m/g,t.m)
					 .replace(/D/g,t.D)
					 .replace(/d/g,t.d)
					 .replace(/H/g,t.H)
					 .replace(/h/g,t.h)
					 .replace(/G/g,t.G)
					 .replace(/g/g,t.g)
					 .replace(/I/g,t.I)
					 .replace(/i/g,t.i)
					 .replace(/S/g,t.S)
					 .replace(/s/g,t.s)
					 .replace(/K/g,['日','一','二','三','四','五','六'][t.K]);
		if (!!allobj) {return t; }
		return t.fmt;
	},
	guid() {
		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
			var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
			return v.toString(16);
		});
	},//guid
	createDown({path,name,headers={},download=false,mthod='GET'}){
		console.log(schemeCheck.test.web(path))
		path=schemeCheck.test.web(path)?path:process.env.VITE_APP_API_BASE_URL+path
		path=path.replace('//','/')
		let toast = Toast.loading('正在准备数据...')
		var xhr = new XMLHttpRequest();
		for (var key in headers) {
			xhr.setRequestHeader(key, headers[key]);
		}
		xhr.open(mthod, path, true);
		xhr.responseType = 'blob';
		xhr.onload = function() {
			toast.destory()
			if (xhr.status === 200) {
				var blob = xhr.response;
				var url = URL.createObjectURL(blob);
				var a = window.document.createElement('a');
				a.href = url;
				if(download) a.download=name
				a.target="_bank"
				a.click();
			}
		};
		xhr.send();
	},//创建下载
	createDownOpen({path,name=''}){
		const el = document.createElement('a')
		el.download=name
		el.href=path
		el.click()
	},//使用浏览器下载
	assignObj({data}){
		arguments.forEach((item,key)=>{
			if(key && item){
				item.forEach((v,k)=>{
					data[k]=v;
				})
			}
		})
	},//数据对象注入

	/**
	 * 简单的跨组件通信事件  vue生命周期内无视组件关系进行通信回调交换数据等 交换的对象与原对象保持同一指向
	 * window:{
	 * 	event_mine:{
	 * 		adds:[
	 * 			{
	 * 				qid,
	 * 				callback,
	 * 			},
	 * 		]
	 * 	}
	 * }
	 **/
    addEvt(name,callback){
        if(!window.event_mine){
            window.event_mine={};
        }
		if(Object.prototype.toString.call(window.event_mine)!='[object Object]'){
			console.error("自定义全局事件监听器注册异常。\n\r请在全局范围内检查window.event_mine是否被占用");
			return;
		}
        if(typeof callback != 'function'){
            myfun.log('回调需要一个function');
            return false;
        }
		if(!window.event_mine[name]){
			window.event_mine[name]=[];
		}
        // window.event_mine[name]=callback;
		const qid = myfun.guid();
		window.event_mine[name].push({
			qid,
			callback,
		})
		return qid;
    },//注册事件监听 返回该监听实例id
    sendEvt({name,value}){
		if(!window.event_mine){
            window.event_mine={};
        }
		let arr = window.event_mine[name];
		if(arr && arr.length>0){
			arr.forEach(item=>{
				item.callback(value)
			})
			return true
		}
		return false;
    },//发送事件 所有已监听都会执行
    removeEvt(name){
		if(window.event_mine){
			delete window.event_mine[name];
			return true;
		}
        return false;
    },//移除监听名
	clearEvt(qid){
		if(window.event_mine){
			for (const key in window.event_mine) {
				if (Object.hasOwnProperty.call(window.event_mine, key)) {
					const element = window.event_mine[key];
					if(element.length>0){
						for (let i = 0; i < element.length; i++) {
							const item = element[i];
							if(item.qid==qid){
								element.splice(i, 1);
								return true;
							}
						}
					}
				}
			}
		}
		return false;
	},//移除指定监听

	/**
	 * js动画定时器  待开发  当前结束值得不到想要的值
	 * @param start 起始值
	 * @param end 结束值
	 * @param fps 帧率
	 * @param useTime 持续时间
	 * @param callback 回调
	 * @param timing 速度曲线  linear匀速默认 ease 从慢快慢 ease-in 慢到块 ease-out 快到慢 待开发
	*/
	animationNum({start=0,end,fps=60,time=500,callback,timing='linear'}){
		let ustime	= 0 //已用时
		let setp	= parseInt(1000/parseInt(fps)) // 刷新间隔时长
		let addnum	= (end-start)/(time/setp)//本次增长值 默认= (start-end )/(time/setp)
		let setnum	= start //当前值
		let rate	= 0.05 //倍率
		let third	= time/setp/3 //3分支1的次数
		let maxrate	= 1.9042;
		let times=0
		let s = setInterval(()=>{
			times++;
			if(timing == 'ease'){
				if(ustime<time/3){
					rate*=rate>=maxrate?maxrate:((maxrate+1.8)/third+1);
				}else if(ustime>time/1.5){
					rate*=rate<=0.05?0.05:(1-3.1/third);
				}
			}else if(timing == 'ease-in'){
				if(ustime<time/3){
					maxrate=1.5015;
					rate*=rate>=maxrate?maxrate:((maxrate+1.8)/third+1);
				}
			}else if(timing == 'ease-out'){
				if(ustime>time/1.5){
					rate*=rate<=0.05?0.05:(1-3.1/third);
				}else{
					rate=1.30367;
				}
			}else{
				rate=1;
			}
			let adds = addnum*rate;
			adds=Math.abs(adds)>Math.abs(addnum*maxrate)?addnum*maxrate:adds;
			setnum += adds;
			// console.log(times,'当前值：',setnum.toFixed(2),'增长：',adds.toFixed(2),'均值:',addnum,'倍率',rate.toFixed(2))
			if(callback) callback(setnum)
			ustime+=setp;
			if(ustime>=time) clearInterval(s)
		},setp)
	},
	/**
	 * 动画计算
	 * @param start 起始值
	 * @param end 结束值
	 * @param fps 帧率
	 * @param useTime 持续时间
	 * @param callback 回调
	 * @param timing 速度曲线  linear匀速默认 ease 从慢快慢 ease-in 慢到块 ease-out 快到慢 待开发
	 */
	animationBezier({start=0,end,fps=60,time=500,callback,timing='linear'}){
		let ustime	= 0 //已用时
		let setp = parseInt(1000/parseInt(fps)) // 刷新间隔时长
		let pointMum = Math.ceil(time/setp);//变化次数
		let changeList = []
		for (let i = 0; i < pointMum; i++) {
			const val = i;
			changeList.push({value:val});
		}
		let times = 0
		let s = setInterval(()=>{
			if(callback) callback(changeList[times])
			times++;
			ustime+=setp;
			if(ustime>=time) clearInterval(s)
		},Math.ceil(time/changeList.length))
	},
	copyText(text,toast){
		let el		= document.createElement('input')
		document.body.appendChild(el)
		el.value	= text
		el.select();
		let bol = document.execCommand('copy')
		document.body.removeChild(el)
		if(toast){
			if(bol){
				Toast.success({message:'复制成功',place:'center'})
			}else{
				Toast.err({message:'复制失败',place:'center'})
			}
		}
		return bol
	},//复制text文本
	copyElContent(el,toast){
		// 有range用range  没range创建range六边形兼容
		let range
		if(window.getSelection().rangeCount==0){
			range=new Range()
			window.getSelection().addRange(range);
		}else{
			range = window.getSelection().getRangeAt(0)
		}
		range.setStart(el, 1)
		range.setEnd(el, 3)
		let bol = document.execCommand('copy')
		range.setEnd(el, 0)
		if(toast){
			if(bol){
				Toast.success({message:'复制成功',place:'center'})
			}else{
				Toast.err({message:'复制失败',place:'center'})
			}
		}
		return bol
	},//复制节点的内容
	/**
	 * 将元素显示到视口位置 top center bottom 上中下 待开发：left middle right 左中右  和 滚动过去的动画
	 * @param {*} el 要显示到视口的元素
	 * @param {*} scrollbox 滚动容器
	 * @param {*} place 位置
	 * @param {*} hold 如果元素已在视口中显示则保持位置不变
	 */
	scrollInToView(el,scrollbox=document.body,place='center',hold=true){
		if(hold==true){
			if(place=='center' || place=='top' || place=='bottom'){
				let max = el.offsetTop - el.offsetHeight
				let min = el.offsetTop - scrollbox.offsetHeight
				// console.log(scrollbox.scrollTop,min,max)
				if(scrollbox.scrollTop>=min && scrollbox.scrollTop<=max) return
			}
		}
		switch(place){
			case 'center':
				scrollbox.scrollTop = el.offsetTop - (scrollbox.offsetHeight + el.offsetHeight)/2
				break;
			case 'top':
				scrollbox.scrollTop = el.offsetTop - el.offsetHeight
				break;
			case 'bottom':
				scrollbox.scrollTop = el.offsetTop - scrollbox.offsetHeight
				break;
			default:
				console.warn('你指定了一个未定义的视口位置给scrollInToView')
		}
	},
	/**
	 * 浏览器标签通信
	 */
	tagMsg(name,callback){
		if(!name) return console.warn('tagMsg 缺少参数 name')
		const {
			isSupported,
			data,
			post,
			error,
			close,
			isClosed,
		}= useBroadcastChannel({ name })
		watch(data, () => {
			if (callback) callback(data.value)
		})
		return {
			isSupported,
			data,
			post,
			error,
			close,
			isClosed,
		}
	},
}

export default {
	ajax,
	$cache		: cache,
	$html2pdf	: html2pdf,
	$checkData	: schemeCheck.checkData,
	$checkForm	: schemeCheck.checkForm,
	$checkTest	: schemeCheck.test,
	...myData,
	...myfun,
	...mediaParse,
	install(Vue){
		Vue.config.globalProperties.$Tajax		= ajax;
		Vue.config.globalProperties.$cache		= cache;
		Vue.config.globalProperties.$html2pdf	= html2pdf
		Vue.config.globalProperties.$checkData= schemeCheck.checkData
		Vue.config.globalProperties.$checkForm= schemeCheck.checkForm
		Vue.config.globalProperties.$checkTest= schemeCheck.test
		for(let key  in myData){
			Vue.config.globalProperties['$'+key]=myData[key];
		}
		for(let key  in myfun){
			Vue.config.globalProperties['$'+key]=myfun[key];
		}
		for(let key  in mediaParse){
			Vue.config.globalProperties['$'+key]=mediaParse[key];
		}

	}

	// app.config.globalProperties
};